"""
审计日志模型
"""
from django.db import models
from django.conf import settings
import json


class AuditLog(models.Model):
    """审计日志"""
    
    ACTION_CHOICES = [
        ('create', '创建'),
        ('update', '更新'),
        ('delete', '删除'),
        ('view', '查看'),
        ('login', '登录'),
        ('logout', '登出'),
        ('export', '导出'),
        ('import', '导入'),
    ]
    
    LEVEL_CHOICES = [
        ('info', '信息'),
        ('warning', '警告'),
        ('error', '错误'),
        ('critical', '严重'),
    ]
    
    user = models.ForeignKey(
        settings.AUTH_USER_MODEL,
        on_delete=models.SET_NULL,
        null=True,
        blank=True,
        verbose_name='操作用户'
    )
    action = models.CharField(max_length=20, choices=ACTION_CHOICES, verbose_name='操作类型')
    level = models.CharField(max_length=20, choices=LEVEL_CHOICES, default='info', verbose_name='日志级别')
    
    # 操作对象信息
    content_type = models.CharField(max_length=100, blank=True, null=True, verbose_name='对象类型')
    object_id = models.PositiveIntegerField(blank=True, null=True, verbose_name='对象ID')
    object_repr = models.CharField(max_length=200, blank=True, null=True, verbose_name='对象描述')
    
    # 操作详情
    message = models.TextField(verbose_name='操作描述')
    changes = models.JSONField(default=dict, blank=True, verbose_name='变更内容')
    
    # 请求信息
    ip_address = models.GenericIPAddressField(blank=True, null=True, verbose_name='IP地址')
    user_agent = models.TextField(blank=True, null=True, verbose_name='用户代理')
    request_path = models.CharField(max_length=500, blank=True, null=True, verbose_name='请求路径')
    request_method = models.CharField(max_length=10, blank=True, null=True, verbose_name='请求方法')
    
    # 时间信息
    timestamp = models.DateTimeField(auto_now_add=True, verbose_name='操作时间')
    
    class Meta:
        db_table = 'audit_logs_audit_log'
        verbose_name = '审计日志'
        verbose_name_plural = '审计日志'
        ordering = ['-timestamp']
        indexes = [
            models.Index(fields=['user', 'timestamp']),
            models.Index(fields=['action', 'timestamp']),
            models.Index(fields=['content_type', 'object_id']),
        ]
        
    def __str__(self):
        return f"{self.user} {self.get_action_display()} {self.object_repr or self.message}"
    
    @classmethod
    def log_action(cls, user, action, message, **kwargs):
        """记录操作日志"""
        return cls.objects.create(
            user=user,
            action=action,
            message=message,
            **kwargs
        )


class SystemLog(models.Model):
    """系统日志"""
    
    LEVEL_CHOICES = [
        ('debug', '调试'),
        ('info', '信息'),
        ('warning', '警告'),
        ('error', '错误'),
        ('critical', '严重'),
    ]
    
    level = models.CharField(max_length=20, choices=LEVEL_CHOICES, verbose_name='日志级别')
    logger_name = models.CharField(max_length=100, verbose_name='日志器名称')
    message = models.TextField(verbose_name='日志消息')
    
    # 异常信息
    exception_type = models.CharField(max_length=100, blank=True, null=True, verbose_name='异常类型')
    exception_message = models.TextField(blank=True, null=True, verbose_name='异常消息')
    stack_trace = models.TextField(blank=True, null=True, verbose_name='堆栈跟踪')
    
    # 上下文信息
    module = models.CharField(max_length=100, blank=True, null=True, verbose_name='模块')
    function = models.CharField(max_length=100, blank=True, null=True, verbose_name='函数')
    line_number = models.PositiveIntegerField(blank=True, null=True, verbose_name='行号')
    
    # 额外数据
    extra_data = models.JSONField(default=dict, blank=True, verbose_name='额外数据')
    
    timestamp = models.DateTimeField(auto_now_add=True, verbose_name='记录时间')
    
    class Meta:
        db_table = 'audit_logs_system_log'
        verbose_name = '系统日志'
        verbose_name_plural = '系统日志'
        ordering = ['-timestamp']
        indexes = [
            models.Index(fields=['level', 'timestamp']),
            models.Index(fields=['logger_name', 'timestamp']),
        ]
        
    def __str__(self):
        return f"[{self.level.upper()}] {self.logger_name}: {self.message[:100]}"


class LoginAttempt(models.Model):
    """登录尝试记录"""
    
    username = models.CharField(max_length=150, verbose_name='用户名')
    ip_address = models.GenericIPAddressField(verbose_name='IP地址')
    user_agent = models.TextField(verbose_name='用户代理')
    
    is_successful = models.BooleanField(verbose_name='是否成功')
    failure_reason = models.CharField(max_length=200, blank=True, null=True, verbose_name='失败原因')
    
    # 安全信息
    is_suspicious = models.BooleanField(default=False, verbose_name='是否可疑')
    country = models.CharField(max_length=100, blank=True, null=True, verbose_name='国家')
    city = models.CharField(max_length=100, blank=True, null=True, verbose_name='城市')
    
    timestamp = models.DateTimeField(auto_now_add=True, verbose_name='尝试时间')
    
    class Meta:
        db_table = 'audit_logs_login_attempt'
        verbose_name = '登录尝试'
        verbose_name_plural = '登录尝试'
        ordering = ['-timestamp']
        indexes = [
            models.Index(fields=['username', 'timestamp']),
            models.Index(fields=['ip_address', 'timestamp']),
            models.Index(fields=['is_successful', 'timestamp']),
        ]
        
    def __str__(self):
        status = "成功" if self.is_successful else "失败"
        return f"{self.username} - {status} - {self.ip_address}"


class DataExportLog(models.Model):
    """数据导出日志"""
    
    STATUS_CHOICES = [
        ('pending', '待处理'),
        ('processing', '处理中'),
        ('completed', '已完成'),
        ('failed', '失败'),
    ]
    
    user = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE, verbose_name='导出用户')
    export_type = models.CharField(max_length=50, verbose_name='导出类型')
    description = models.CharField(max_length=200, verbose_name='导出描述')
    
    # 导出参数
    filters = models.JSONField(default=dict, blank=True, verbose_name='过滤条件')
    fields = models.JSONField(default=list, blank=True, verbose_name='导出字段')
    
    # 状态信息
    status = models.CharField(max_length=20, choices=STATUS_CHOICES, default='pending', verbose_name='状态')
    file_path = models.CharField(max_length=500, blank=True, null=True, verbose_name='文件路径')
    file_size = models.PositiveIntegerField(blank=True, null=True, verbose_name='文件大小')
    record_count = models.PositiveIntegerField(blank=True, null=True, verbose_name='记录数量')
    
    # 时间信息
    started_at = models.DateTimeField(blank=True, null=True, verbose_name='开始时间')
    completed_at = models.DateTimeField(blank=True, null=True, verbose_name='完成时间')
    created_at = models.DateTimeField(auto_now_add=True, verbose_name='创建时间')
    
    # 错误信息
    error_message = models.TextField(blank=True, null=True, verbose_name='错误信息')
    
    class Meta:
        db_table = 'audit_logs_data_export'
        verbose_name = '数据导出日志'
        verbose_name_plural = '数据导出日志'
        ordering = ['-created_at']
        
    def __str__(self):
        return f"{self.user.username} - {self.export_type} - {self.get_status_display()}"
    
    @property
    def duration(self):
        """导出耗时"""
        if self.started_at and self.completed_at:
            return self.completed_at - self.started_at
        return None
